#!/usr/bin/env python
#-------------------------------python------------------demoturtle.py--#
#                                                                      #
#                       Demo di turtlegraphics                         #
#                                                                      #
#--Daniele Zambelli----------------------------------------------2003--#

from random import random, randrange
from pyturtle import *
#from math import pi, atan2

"""
Demo dei metodi di Turtle presenti nella libreria PyTurtle
"""

# init
tina=Turtle()

# version
def versione():
  '''Stampa la versione corrente della libreria'''
  print "Versione corrente",tina.version()

# after
def quadratoafter(lato):
  '''Disegna un quadrato fermandosi mezzo secondo ad ogni vertice'''
  for i in range(4):
    tina.forward(lato)
    tina.after(500)
    tina.left(90)

# forward
def quadrato(lato):
  '''Disegna un quadrato con un certo lato'''
  for i in range(4):
    tina.forward(lato)
    tina.left(90)

# back
def albero(l):
  '''Disegna un albero ricorsivo con il tronco lungo l'''
  if l>2:
    tina.forward(l)
    tina.left(45)
    albero(l*0.8)
    tina.right(90)
    albero(l*0.6)
    tina.left(45)
    tina.back(l)

# left
def filaalberi(n, l):
  '''Disegna n alberelli di tronco l'''
  for i in range(n):
    tina.left(90)
    albero(l)
    tina.right(90)
    spostati(l*4, 0)
  spostati(-l*4*n, 0)

# right
def stella(n, l):
  '''Disegna una stella con enne raggi lungli elle'''
  for i in range(n):
    tina.forward(l); tina.back(l)
    tina.right(360./n)

# up
def spostati(x, y):
  '''Trasla Tartaruga delle componenti x e y'''
  tina.up()
  tina.forward(x)
  tina.left(90)
  tina.forward(y)
  tina.right(90)
  tina.down()

# down
def tratteggia(l, p):
  '''Traccia una linea tratteggiata lunga l con passo p'''
  for i in range(l/p):
    tina.forward(float(p)/2)
    tina.up()
    tina.forward(float(p)/2)
    tina.down()
  tina.forward(l % p)

def quadratotratt(l, p):
  '''Disegna un quadrato tratteggiato'''
  titolo("Quadrato tratteggiato")
  tina.setwidth(3); coloraacaso()
  for i in range(4):
    tratteggia(l, p); tina.left(90)
  
# write
def titolo(s):
  '''Scrive la stringa s in alto a sinistra'''
  piano=tina.getplane()
  p, d = tina.getpos(), tina.getdir()
  tina.up(); tina.setpos((piano._s2x(20), piano._s2y(20)))
  tina.write(s)
  tina.up(); tina.setpos(p); tina.setdir(d); tina.down()
  
# fill
def quadratopieno(lato, colore):
  '''Disegna un quadrato con l'interno colorato'''
  tina.fill(1)
  quadrato(lato)
  c=tina.getcolor()
  tina.setcolor(colore)
  tina.fill(0)
  tina.setcolor(c)

# tracer
def girodellamorte(l):
  '''Disegna una traccia circolare variando
  la velocita' e lo spessore'''
  titolo("Giro della morte (cambia lo spessore della penna e la velocita')")
  tina.up(); tina.left(90); tina.back(200); tina.right(90); tina.down()
  coloraacaso()
  passi=72; angolo=180./72
  for i in range(passi):
    altezza=(tina.getpos()[1]+200)/20
    tina.setwidth(altezza)
    tina.tracer(altezza)
    tina.left(angolo)
    tina.forward(l)
    tina.left(angolo)

# setpos
def saltaacaso():
  '''Sposta casualmente Tartaruga all'interno del rettangolo
  di vertici (0, 0) e (600, 400)'''
  tina.up()
  tina.setpos((randrange(600)-300, randrange(400)-200))
  tina.down()

# setdir
def spostaacaso(raggio):
  '''Ruota a caso Tartaruga e la sposta all'interno di un
  cerchio di dato raggio'''
  tina.up()
  tina.setpos((0, 0))
  tina.setdir(randrange(360)); tina.forward(randrange(raggio))
  tina.down()
              
def cielo(n):
  '''Disegna un cielo stellato'''
  titolo("Un cielo con %i stelle" % n)
  tina.fill(1); tina.ccircle(200); tina.fill(0)
  for i in range(n):
    spostaacaso(190)
    coloraacaso()
    stella(5, 10)
  
# setcolor
def coloraacaso():
  '''Assegna a Tartaruga un colore con componenti RGB casuali'''
  tina.setcolor(random(), random(), random())

# setwidth
def fila(n, l, d):
  '''Disegna una fila di n quadrati e cerchi alternati'''
  tina.setwidth(3)
  for i in range(n):
    if i % 2:
      tina.circle(l/2)
    else:
      quadratopieno(l, "maroon")
    spostati(d, 0)
  spostati(-d*n, 0)

# getpos
def trirett(cateto1, cateto2):
  '''Disegna un triangolo rettangolo dati i due cateti'''
  tina.forward(cateto1)
  a=tina.getpos()
  tina.back(cateto1)
  tina.left(90)
  tina.forward(cateto2)
  tina.setpos(a)
  tina.right(90)
  tina.back(cateto1)

def inviluppo(l1, l2, inc=10):
  '''Disegna un inviluppo di triangoli rettangoli'''
  if l1<0: return
  trirett(l1, l2)
  inviluppo(l1-inc, l2+inc)

def quadrinviluppo(dimensione):
  '''Disegna quattro inviluppi di triangoli rettangoli'''
  coloraacaso()
  titolo("Inviluppo di triangoli rettangoli")
  for i in range(4):
    inviluppo(dimensione, 0)
    tina.left(90)
   
# getdir
def printdir():
  '''Modifica a caso la direzione di Tartaruga
  e la scrive sullo schermo'''
  tina.left(randrange(360))
  tina.write("direzione di tina %i" % tina.getdir())

# getcolor
def printcolor():
  '''Sceglie un colore a casao e lo scrive sullo schermo'''
  coloraacaso()
  tina.write("attuale colore della tartaruga: "+str(tina.getcolor()))

# getwidth
def printwidth():
  '''Modifica casualmente la larghezza della penna e
  la scrive sullo schermo'''
  tina.setwidth(randrange(10))
  tina.write("Larghezza della penna: %i" % tina.getwidth())
  
def datiturtle():
  '''Modifica gli attributi di Tartaruga e li scrive sullo schermo'''
  titolo("Dati relativi alla tartaruga")
  printcolor()
  tina.left(45); tina.forward(80)
  printwidth()
  tina.forward(80)
  printdir()
  tina.forward(80)
  
# reset
def vettorir(n):
  '''Disegna per enne volte quattro segmenti consecutivi
  ripartendo sempre dall'origine'''
  tina.tracer(1)
  for i in range(n):
    tina.reset()
    titolo("Segmenti consecutivi che partono dall'origine")
    tina.setwidth(randrange(2, 20, 2))
    for j in range(4):
      tina.right(randrange(360))
      coloraacaso()
      tina.forward(randrange(100))
      coloraacaso()

# clear
def vettoric(n):
  '''Disegna per enne volte quattro segmenti consecutivi
  ripartendo dalla posizione dove era stata lasciata tartaruga'''
  tina.tracer(1)
  for i in range(n):
    tina.clear()
    titolo("Segmenti consecutivi")
    tina.setwidth(randrange(2, 20, 2))
    for j in range(4):
      tina.right(randrange(360))
      coloraacaso()
      tina.forward(randrange(100))
      coloraacaso()

# circle
def macchie(n):
  '''Per tre volte pulisce lo schermo e disegna n gerchi colorati'''
  for i in range(3):
    tina.clear()
    titolo("macchie colorate")
    for j in range(n):
      saltaacaso()
      coloraacaso()
      tina.fill(1)
      tina.circle(randrange(100), randrange(360))
      tina.fill(0)

def tricircle():
  '''Produce uno strano disegno'''
  tina.tracer(1)
  tina.setwidth(10)
  tina.fill(1)
  for i in range(3):
    tina.forward(100)
#    print tina.getpos()
    tina.right(90)
    tina.setcolor("green")
    tina.circle(30)
    tina.setcolor("black")
    tina.left(90)
    tina.back(80)
    tina.left(120)
  tina.setcolor("maroon")
  tina.fill(0)

# ccircle
def bersaglio():
  '''Disegna un bersaglio'''
  saltaacaso()
  stella(4, 5)
  larghezza=tina.getwidth()
  tina.setwidth(2)
  tina.ccircle(20)
  tina.setwidth(larghezza)
  tina.ccircle(10)
  return(tina.getpos())

# radians
from time import time, localtime

def ora(dimensione):
  '''Disegna un orologio analogico con l'ora di sistema'''
  titolo("L'ora attuale e'")
  quadrante(dimensione)
  lancette(dimensione, localtime(time())[3:6])
  
def quadrante(dimensione):
  '''Il quadrante di un orologio'''
  tina.radians()
  tina.up(); tina.forward(dimensione); tina.down()
  tina.left(pi/2)
  tina.circle(dimensione)
  tina.right(pi/2)
  tina.up(); tina.back(dimensione); tina.down()
  d1=dimensione*0.9; d2=dimensione-d1
  for i in range(12):
    tina.up(); tina.forward(d1); tina.down()
    tina.forward(d2)
    tina.up(); tina.back(dimensione); tina.down()
    tina.left(pi/6)
  tina.degrees()

# degrees
def lancette(d, (ore, minuti, secondi)):
  '''Disegna le lancette di un orologio che segna ore:minuti:secondi'''
  tina.degrees()
  aore=round(90 - ore*30 - minuti*0.5)
  aminuti=round(90 - minuti*6 - secondi*0.1)
  asecondi=round(90 - secondi*6)
  tina.setdir(aore)
  tina.setwidth(d*0.1)
  tina.forward(d*0.6)
  tina.back(d*0.6)
  tina.setdir(aminuti)
  tina.setwidth(d*0.05)
  tina.forward(d*0.8)
  tina.back(d*0.8)
  tina.setdir(asecondi)
  tina.setwidth(d*0.02)
  tina.forward(d*0.9)
  tina.back(d*0.9)

# getplane
def raggi(n, l):
  '''Crea 36 tartarughe all'interno dello stesso piano
  mettendole in una lista, poi le fa muovere'''
  titolo("36 tartarughe che eseguono gli stessi comandi")
  p=tina.getplane()
  tartarughe=[]
  for i in range(n):
    tartarughe.append(Turtle(p))
  for i in range(len(tartarughe)):
    tartarughe[i].left(360/n*i)
  for t in tartarughe: t.forward(l)
  for t in tartarughe: t.left(90)
  for t in tartarughe: t.forward(l/4)
  for t in tartarughe: t.right(45)
  for t in tartarughe: t.forward(l)
  for t in tartarughe: t.right(120)
  for t in tartarughe: t.forward(l/2)
  for t in tartarughe: t.left(60)
  for t in tartarughe: t.forward(l/2)
    
# distance
def prendiformaggio():
  '''Dirige Tartaruga verso un bersaglio emulando l'olfatto'''
  titolo("Ricerca in base all'odore")
  b=bersaglio()
  saltaacaso()
  ricerca_per_odore(b)

def odore(p):
  '''Riporta un numero inversamente proporzionale
  alla distanza da p'''
  return 1./(tina.distance(p)**2)

def ricerca_per_odore(bersaglio):
  '''Muove Tartaruga in base ad una regola olfattiva'''
  tina.tracer(2)
  ricordo_odore=odore(bersaglio)
  while tina.distance(bersaglio)>10:
    tina.forward(randrange(10))
    nuovo_odore=odore(bersaglio)
    if nuovo_odore<ricordo_odore:
      tina.right(randrange(80))
    ricordo_odore=nuovo_odore
  
# dirto
class Topo(Turtle):
  '''Classe che simula il comportamento di un topo'''
  def __init__(self):
    Turtle.__init__(self)
    piano=self._plane
    self.up(); self.setpos((piano._s2x(20), piano._s2y(20)))
    self.write("inseguimento in base alla vista")
    self.setpos((randrange(120)-60, randrange(80)-40))
    self.down()

  def scappa(self, da):
    '''Fa muovere il topo di un passo cercando di scappare da da'''
    dir_gatto=self.dirto(da.getpos())
    if dir_gatto<170:
      self.right(randrange(20)-10)
    elif dir_gatto>-170:
      self.left(randrange(20)-10)
    else:
      self.left(randrange(80)-40)
    self.forward(1)

class Gatto(Turtle):
  '''Classe che simula il comportamento di un gatto'''
  def __init__(self, piano):
    Turtle.__init__(self, piano)
    self.setcolor("red")
    self.setwidth(3)

  def insegui(self, chi):
    '''Fa muovere il gatto di un passo come se inseguisse chi
    ritorna 0 se ha raggiunto chi'''
    if self.distance(chi.getpos())<3:
      self.setpos(chi.getpos())
      return 0
    dir_topo=self.dirto(chi.getpos())
    if dir_topo<180: self.left(randrange(5))
    else:            self.right(randrange(5))
    self.forward(2)
    return 1

def insegui():
  '''Simula l'inseguimento tra un gatto e un topo'''
  topo=Topo()
  gatto=Gatto(topo.getplane())
  while gatto.insegui(topo): topo.scappa(gatto)

# whereis
def prendilombrico():
  titolo("Ricerca in base all'udito")
  b=bersaglio()
  saltaacaso()
  ricerca_per_udito(b)

def intensita_destra(distanza, angolo):
  '''Restituisce un numero che indica l'intensita' con cui
  l'orecchio destro ode un suono proveniente da un bersaglio
  posto ad una certa distanza e con un certo angolo'''
  senangolo = sin((angolo % 360)*pi/180)
  if senangolo<0:
    return -10.*senangolo/(distanza**2)
  else:
    return 5.*senangolo/(distanza**2)

def intensita_sinistra(distanza, angolo):
  '''Restituisce un numero che indica l'intensita' con cui
  l'orecchio sinistro ode un suono proveniente da un bersaglio
  posto ad una certa distanza e con un certo angolo'''
  senangolo = sin((angolo % 360)*pi/180)
  if senangolo>0:
    return 10.*senangolo/(distanza**2)
  else:
    return -5.*senangolo/(distanza**2)

def ricerca_per_udito(bersaglio):
  '''Simula la ricerca di un bersaglio utilizzando l'udito'''
  tina.tracer(10)
  while tina.distance(bersaglio)>10:
    d, a = tina.whereis(bersaglio)
    tina.forward(randrange(5))
    if intensita_destra(d, a)>intensita_sinistra(d, a):
      tina.right(randrange(30))
    else:
      tina.left(randrange(30))

# lookat
def parabola(p):
  '''Disegna una parabola per mezzo dell'inviluppo di rette'''
  titolo("Parabola formata da un inviluppo di rette")
  numpassi=80
  lato=5
  tina.up(); tina.back(200); tina.down()
  for i in range(numpassi):
    asse(p)
    tina.forward(lato)

def asse(punto):
  '''Disegna l'asse del segmnento che ha per estremi Tartaruga e punto'''
  dir=tina.getdir()
  pos=tina.getpos()
  tina.up()
  tina.lookat(punto)
  tina.forward(tina.distance(punto)/2.)
  tina.left(90); tina.back(1000)
  tina.down(); tina.forward(2000); tina.up()
  tina.setpos(pos); tina.setdir(dir)
  tina.down()

# hide e show

def cucu():
  '''Traccia una linea mostrando e nascondendo Tartaruga'''
  tina.up()
  tina.back(295)
  tina.down()
  tina.tracer(10)
  for i in range(15):
    tina.forward(19)
    tina.hide()
    tina.forward(19)
    tina.show()

# save
def alberelli():
  '''Produce un disegno e lo salva nel file immagine.png.
  .Funziona solo con Linux perche' utilizza il programma convert'''
  titolo('Demo di PyTurtle')
  spostati(-60*2, 0)
  fila(5, 20, 60)
  spostati(10, 20)
  filaalberi(3, 30)
  tina.save('immagine')
 
def demo():
  '''Demo di PyTurtle: esegue almeno una volta tutti i metodi di Turtle'''
  global tina
##  versione()
##  ora(150)
##  tina.mainloop()
##  tina=Turtle()
##  quadratoafter(100)
##  tina.mainloop()
##  tina=Turtle()
##  cucu()
##  tina.mainloop()
##  tina=Turtle()
##  macchie(100)
##  tina.mainloop()
##  tina=Turtle()
##  vettorir(3)
##  vettoric(3)
##  tina.mainloop()
##  tina=Turtle()
##  girodellamorte(16)
##  tina.mainloop()
##  tina=Turtle()
##  quadrinviluppo(200)
##  tina.mainloop()
##  tina=Turtle()
##  cielo(100)
##  tina.mainloop()
##  tina=Turtle()
##  quadratotratt(193, 10)
##  tina.mainloop()
##  tina=Turtle()
##  raggi(36, 80)
##  tina.mainloop()
##  tina=Turtle()
##  datiturtle()
##  tina.mainloop()
##  tina=Turtle()
##  parabola((0, 50))
##  tina.mainloop()
##  tina=Turtle()
  prendiformaggio()
  tina.mainloop()
  tina=Turtle()
  prendilombrico()
  tina.mainloop()
  tina=Turtle()
  insegui()  # crea due finestre grafiche
  tina.mainloop()
  tina=Turtle()
  alberelli()
  tina.mainloop()
  
if __name__ == "__main__": demo()
